/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.Net;
using System.Windows.Threading;
using Microsoft.Win32;
using System.Windows.Media;

namespace Oceanside
{
    public class Constants
    {
        public static Action EmptyDelegate = delegate() { };

        public const string NEWLINE = "\n";
        public const string SPACES = "     ";

        public const int CONST_DB_RETRIES = 1;
        public const int CONST_TOTAL_PRINTER_NOTE_WIDTH = 3;
        public const int CONST_MAX_RECEIPT_QUANTITY_ORDERED_WIDTH = 4;
        public const int CONST_MAX_REPORT_LINE_NUM_WIDTH = 10;


        public const int CONST_SEATSCHECKS_PER_SCROLL_AREA = 4;
        public const int CONST_TOTAL_INIT_STEPS = 65;
        public const int CONST_CHARS_IN_POS_LOGIN = 6;
        public const int CONST_MAX_ROLES_PER_USER = 4;
        public const string CONST_GATEWAY_INIT_FAILURE_MESSAGE = "The system was not able to initialize the payment gateway at this time.  Each time you attempt to process a card transaction, the system will retry the initialization process until successful.  In the mean time, please assure that you are able to communicate with the Internet.  To help protect you and your customers, it is important to note that Oceanside POS ® does not save cardholder data and a live Internet connection is necessary to process a credit card transaction. Oceanside POS ® is PA-DSS compliant.";

        public static int CONST_ROWS_PER_VIEW
        {
            get
            {
                if (IsQuickServiceMode) 
                    return 5;
                else
                    return 8;
            }
        }
        public const int CONST_BUTTN_PER_ROW = 3;
        public static int CONST_BUTTN_PER_SUBVIEW
        {
            get
            {
                return CONST_ROWS_PER_VIEW * CONST_BUTTN_PER_ROW;
            }
        }

        public const int CONST_LINE_ITEMS_PER_SPLIT_WINDOW_VIEW = 21;
        public static int CONST_LINE_ITEMS_PER_CHECK_WINDOW_VIEW
        {
            get
            {
                if (IsQuickServiceMode) 
                    return 11;
                else
                    return 21;
            }
        }
#if _LOCALDB
        public static string RELAUNCH_DIRECTORY = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
            @"\Oceanside Software Corporation\Oceanside POS\Demo\";
#else
        public static string RELAUNCH_DIRECTORY = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
            @"\Oceanside Software Corporation\Oceanside POS\";
#endif
        public static string RELAUNCH_DIR_AND_PROGRAM = RELAUNCH_DIRECTORY + "oceansidepos.exe";

        public static string CONST_DATA_DIR = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
            + @"\.588E83E9-9CD2-44ED-A7FC-26F430A4439E";

        public static string CONST_MAILEME_FOLDER = @"C:\MailMe";


        /// <summary>
        /// 
        /// </summary>
        public static INotifyError ErrorDispatcher;


        private static Dispatcher mainDispatcher;
        public static Dispatcher MainDispatcher
        {
            get { return mainDispatcher; }
            set { mainDispatcher = value; }
        }

        private static bool isTestMode = false;
        public static bool IsTrainingMode
        {
            get { return Constants.isTestMode || Constants.IsLocalDbMode; }
            set { Constants.isTestMode = value; }
        }

#if _LOCALDB
        public static bool IsLocalDbMode = true;
#else
        public static bool IsLocalDbMode = false;
#endif

        private static bool hasCfd = false;
        public static bool HasCfd
        {
            get { return hasCfd; }
            set { hasCfd = value; }
        }

        private static int cfdType = 1;
        public static int CfdType
        {
            get { return cfdType; }
            set { cfdType = value; }
        }

        private static string cfdCom = "";
        public static string CfdCom
        {
            get { return cfdCom; }
            set { cfdCom = value; }
        }

        private static string cfdLine1 = "";
        public static string CfdLine1
        {
            get { return cfdLine1; }
            set { cfdLine1 = value; }
        }

        private static string cfdLine2 = "";
        public static string CfdLine2
        {
            get { return cfdLine2; }
            set { cfdLine2 = value; }
        }

        private static string proxyMailServer = "smtp.gmail.com";
        public static string ProxyMailServer
        {
            get { return Constants.proxyMailServer; }
            set { Constants.proxyMailServer = value; }
        }
        private static int proxyMailServerPort = 587;
        public static int ProxyMailServerPort
        {
            get { return Constants.proxyMailServerPort; }
            set { Constants.proxyMailServerPort = value; }
        }
        private static bool proxyMailServerUsesSsl = true;
        public static bool ProxyMailServerUsesSsl
        {
            get { return Constants.proxyMailServerUsesSsl; }
            set { Constants.proxyMailServerUsesSsl = value; }
        }



        /// <summary>
        /// My oceanside mag cards were encoded with this number
        /// That should be on your mag cards.  I changed the number
        /// here, you can choose anything you want.
        /// </summary>
        private static string magCardLoginToken = "123456789";
        public static string MagCardLoginToken
        {
            get { return Constants.magCardLoginToken; }
            set { Constants.magCardLoginToken = value; }
        }


        /// <summary>
        /// 
        /// </summary>
        private static bool isQuickServiceMode = false;
        public static bool IsQuickServiceMode
        {
            get { return isQuickServiceMode; }
            set { isQuickServiceMode = value; }
        }

        private static string versionInRegistry = null;
        public static string VersionInRegistry
        {
            get { return Constants.versionInRegistry; }
            set { Constants.versionInRegistry = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        private static bool showMouseCursor = true;
        public static bool ShowMouseCursor
        {
            get { return Constants.showMouseCursor; }
            set { Constants.showMouseCursor = value; }
        }

        private static bool _forceOrderOnScreenSaverTimeout = true;
        public static bool ForceOrderOnScreenSaverTimeout
        {
            get { return Constants._forceOrderOnScreenSaverTimeout; }
            set { Constants._forceOrderOnScreenSaverTimeout = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        private static bool menuIsInitialized = false;
        public static bool MenuIsInitialized
        {
            get { return Constants.menuIsInitialized; }
            set { Constants.menuIsInitialized = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        private static bool hasPaymentGateway = false;
        public static bool HasPaymentGateway
        {
            get { return Constants.hasPaymentGateway; }
            set { Constants.hasPaymentGateway = value; }
        }

        private static bool hasCoinDispenser = false;
        public static bool HasCoinDispenser
        {
            get { return Constants.hasCoinDispenser; }
            set { Constants.hasCoinDispenser = value; }
        }

        static IPHostEntry _ipHostName;
        public static IPHostEntry IpHostName
        {
            get 
            {
                if (_ipHostName == null)
                {
                    InitIp();
                }
                return Constants._ipHostName; 
            }

            set { Constants._ipHostName = value; }
        }


        static string printServerPassword;
        public static string PrintServerPassword
        {
            get { return Constants.printServerPassword; }
            set { Constants.printServerPassword = value; }
        }

        static string systemPassword;
        public static string SystemPassword
        {
            get { return Constants.systemPassword; }
            set { Constants.systemPassword = value; }
        }

        private static string printServerPath = "\\\\localhost";
        public static string PrintServerPath
        {
            get { return Constants.printServerPath; }
            set { Constants.printServerPath = value; }
        }

        private static string printServerUserName = "";
        public static string PrintServerUserName
        {
            get { return Constants.printServerUserName; }
            set { Constants.printServerUserName = value; }
        }
        public static string TouchConfigUtil
        {
            get;
            set;
        }

        private static bool isCustomBrandedLicense = false;
        public static bool IsCustomBrandedLicense
        {
            get { return Constants.isCustomBrandedLicense; }
            set { Constants.isCustomBrandedLicense = value; }
        }

        private static bool forceCashDrop = false;
        public static bool ForceCashDrop
        {
            get { return Constants.forceCashDrop; }
            set { Constants.forceCashDrop = value; }
        }

        private static decimal forceCashDropAmount = 400;
        public static decimal ForceCashDropAmount
        {
            get { return Constants.forceCashDropAmount; }
            set { Constants.forceCashDropAmount = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void InitIp()
        {
            _ipHostName = Dns.GetHostEntry(System.Net.Dns.GetHostEntry("localhost").HostName);
//#if !_LOCALDB
//            IPAddress _ipAddress = null;
//            ///Grab the network interface for the Oceanside sub
//            foreach (IPAddress ip in _ipHostName.AddressList)
//            {
//                if (ip.ToString().Contains("217"))
//                {
//                    _ipAddress = ip;
//                    break;
//                }
//            }

//            if (_ipAddress == null)
//            {
//                App.HadIpAddressInitFailure = true;
//            }
//#endif
        }

        public static void GetSysConfigValues()
        {
            string sysConfig = Oceanside.Driver.UnDrive();
            string[] values = sysConfig.Trim().Split('\n');
            PrintServerPath = "\\\\" + values[5];
            PrintServerUserName = values[6];
            PrintServerPassword = values[7];
            SystemPassword = values[8];

            if (values.Length > 9)
            {
                string stringBool = values[9];
                IsCustomBrandedLicense = stringBool != null && stringBool.Equals("true", StringComparison.CurrentCultureIgnoreCase);
            }
        }

        private static string _updateServerPath = "";
        public static string UpdateServerPath
        {
            get { return Constants._updateServerPath; }
            set { Constants._updateServerPath = value; }
        }

        public static bool IsUsingDevelopmentBuild
        {
            get;
            set;
        }

        public const string HKEY_PROGRAMROOT = "HKEY_LOCAL_MACHINE\\Software\\242AF2AF-5DA4-4840-89F1-7B0884BC8F05\\";

        /// <summary>
        /// 
        /// </summary>
        public static void ReadRegistryValues()
        {
            try
            {
                object pagO = Registry.GetValue(HKEY_PROGRAMROOT, "HASPAYG", 1);
                object qsO = Registry.GetValue(HKEY_PROGRAMROOT, "ISQS", 0);
                object mcO = Registry.GetValue(HKEY_PROGRAMROOT, "MC", 1);
                object touchConfigUtilO = Registry.GetValue(HKEY_PROGRAMROOT, "TOUCHCFG", null);
                object udsPath = Registry.GetValue(HKEY_PROGRAMROOT, "UDSDIRPATH", null);
                object hasCfdO = Registry.GetValue(HKEY_PROGRAMROOT, "HASCFD", null);
                object cfdTypeO = Registry.GetValue(HKEY_PROGRAMROOT, "CFDTYPE", null);
                object cfdComO = Registry.GetValue(HKEY_PROGRAMROOT, "CFDCOM", null);
                object cfdLine1O = Registry.GetValue(HKEY_PROGRAMROOT, "CFDL1", null);
                object cfdLine2O = Registry.GetValue(HKEY_PROGRAMROOT, "CFDL2", null);
                object fcdO = Registry.GetValue(HKEY_PROGRAMROOT, "FCD", null);
                object fcdaO = Registry.GetValue(HKEY_PROGRAMROOT, "FCDA", null);
                object hasCoindO = Registry.GetValue(HKEY_PROGRAMROOT, "HASCOIND", null);
                object proxyMailPortO = Registry.GetValue(HKEY_PROGRAMROOT, "MAILPROXYPORT", null);
                object proxyMailServerO = Registry.GetValue(HKEY_PROGRAMROOT, "MAILPROXYSERVER", null);
                object proxyMailUseSslO = Registry.GetValue(HKEY_PROGRAMROOT, "MAILPROXYUSESSL", null);

                if (proxyMailPortO != null)
                {
                    ProxyMailServerPort = (int)proxyMailPortO;
                }
                if (proxyMailServerO != null)
                {
                    ProxyMailServer = proxyMailServerO as string;
                }
                if (proxyMailUseSslO != null)
                {
                    proxyMailServerUsesSsl = ((int)proxyMailUseSslO) == 1;
                }

                if (hasCoindO != null)
                {
                    HasCoinDispenser = ((int)hasCoindO) == 1;
                }


                ///Set the location of the touch configuration utility.
                if (udsPath != null)
                {
                    UpdateServerPath = udsPath as string;
                    if (UpdateServerPath.Contains("dev"))
                    {
                        IsUsingDevelopmentBuild = true;
                    }
                    else
                    {
                        IsUsingDevelopmentBuild = false;
                    }
                }

                ///Set the location of the touch configuration utility.
                if (touchConfigUtilO != null)
                {
                    TouchConfigUtil = touchConfigUtilO as string;
                }

                int HASPAYG = 1;
                int ISQS = 0;
                int MC = 1;

                if (pagO != null)
                {
                    HASPAYG = (int)pagO;
                }
                else
                {
                    Logging.LogMessage("Could not read HASPAYG Value");
                }
                if (qsO != null)
                {
                    ISQS = (int)qsO;
                }
                else
                {
                    Logging.LogMessage("Could not read ISQS Value");
                }
                if (mcO != null)
                {
                    MC = (int)mcO;
                }
                else
                {
                    Logging.LogMessage("Could not read MC Value");
                }

                if (fcdO != null)
                {
                    if (((int)fcdO) == 1)
                    {
                        ForceCashDrop = true;
                    }
                }

                if (fcdaO != null)
                {
                    ForceCashDropAmount = (decimal)(int)fcdaO;
                }

                ///Customer facing display.
                if (hasCfdO != null)
                {
                    HasCfd = ((int)hasCfdO == 1);

                    if (HasCfd)
                    {
                        if (cfdTypeO != null)
                        {
                            CfdType = (int)cfdTypeO;

                            if (cfdComO != null)
                            {
                                CfdCom = (string)cfdComO;

                                if (cfdLine1O != null)
                                {
                                    CfdLine1 = (string)cfdLine1O;
                                    if (CfdLine1 == null || CfdLine1.Length == 0)
                                    {
                                        CfdLine1 = "Oceanside Software";
                                    }
                                    else if (CfdLine1.Length > 20)
                                    {
                                        CfdLine1 = CfdLine1.Substring(0, 20);
                                    }
                                }
                                if (cfdLine2O != null)
                                {
                                    CfdLine2 = (string)cfdLine2O;
                                    if (CfdLine2 == null || CfdLine2.Length == 0)
                                    {
                                        CfdLine2 = "Dallas, TX 75001";
                                    }
                                    else if (CfdLine2.Length > 20)
                                    {
                                        CfdLine2 = CfdLine2.Substring(0, 20);
                                    }
                                }
                            }
                            else
                            {
                                HasCfd = false;
                            }
                        }
                        else
                        {
                            HasCfd = false;
                        }
                    }
                }

                object verO = Registry.GetValue(HKEY_PROGRAMROOT, "VERSION", null);
                if (verO != null)
                {
                    versionInRegistry = (string)verO;
                }
                else
                {
                    Logging.LogMessage("Could not read Version Value");
                }

                ///Hard Code has payment gateway to false because we cannot include the payment interface as we are under an NDA.
                if (HASPAYG == 1)
                {
                    hasPaymentGateway = false;
                }
                else
                {
                    hasPaymentGateway = false;
                }
                if (ISQS == 1)
                {
                    isQuickServiceMode = true;
                }
                else
                {
                    isQuickServiceMode = false;
                }
#if _LOCALDB
                showMouseCursor = true;
#else
                if (MC == 1)
                {
                    showMouseCursor = true;
                }
                else
                {
                    showMouseCursor = false;
                }
#endif
            }
            catch
            {
                isQuickServiceMode = false;
                showMouseCursor = true;
                hasPaymentGateway = true;
                throw;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rev"></param>
        public static void SetRegistryVersionRev(string rev)
        {
            string root = "HKEY_LOCAL_MACHINE\\Software\\242AF2AF-5DA4-4840-89F1-7B0884BC8F05\\";
            Registry.SetValue(root, "VERSION", rev);
        }


        /// <summary>
        /// 
        /// </summary>
        private static int screenSaverTimeout_MS = 120000;
        public static int ScreenSaverTimeout_MS
        {
            get
            {
                return screenSaverTimeout_MS;
            }
            set
            {
                screenSaverTimeout_MS = value;
            }
        }

        private static int printQueueTimeout_MS = 120000;
        public static int PrintQueueTimeout_MS
        {
            get { return Constants.printQueueTimeout_MS; }
            set { Constants.printQueueTimeout_MS = value; }
        }

        public static void LoadBrushes()
        {
            if (App.CorporateResourceDictionary != null)
            {
                object o = App.CorporateResourceDictionary["ClosedPaymentPanelBackgroundColor"];
                if (o != null)
                {
                    PaymentBackgroundConverter.ClosedTableBrush = o as Brush;
                }

                o = App.CorporateResourceDictionary["DefaultPaymentPanelBackgroundColor"];
                if (o != null)
                {
                    PaymentBackgroundConverter.DefaultBrush = o as Brush;
                }

                o = App.CorporateResourceDictionary["ClosedCheckBackgroundColor"];
                if (o != null)
                {
                    CheckBackgroundConverter.ClosedTableBrush = o as Brush;
                }

                o = App.CorporateResourceDictionary["DefaultCheckBackgroundColor"];
                if (o != null)
                {
                    CheckBackgroundConverter.DefaultBrush = o as Brush;
                }
            }
        }
    }
}
